﻿using System.ComponentModel;
using System.Linq;
using System.Reflection;

namespace Armon.Lib.Type
{
    public static class EnumExtension
    {
        public static string GetDescription(this Enum e)
        {
            var type = e.GetType();

            var members = type.GetMember(e.ToString());
            if (members == null || members.Length <= 0)
            {
                return e.ToString();
            }

            var attributes = members[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
            if (attributes == null || attributes.Length <= 0)
            {
                return e.ToString();
            }

            return ((DescriptionAttribute)attributes[0]).Description;
        }

        public static IEnumerable<string> GetDescriptions<T>() where T : Enum
        {
            return typeof(T).GetFields()
                .Select(a => a.GetCustomAttribute<DescriptionAttribute>())
                .Where(a => a is not null)
                .Select(a => a!.Description);
        }

        public static Dictionary<string, string> ToNameDictionary<T>() where T : Enum
        {
            return typeof(T).GetFields()
                .Where(f => f.FieldType.IsEnum)
                .ToDictionary(f => f.Name, a => a.GetCustomAttribute<DescriptionAttribute>()?.Description ?? "");
        }

        public static Dictionary<int, string> ToDictionary<T>() where T : Enum
        {
            return typeof(T).GetFields()
                .Where(f => f.FieldType.IsEnum)
                .ToDictionary(f => (int)(f.GetValue(null) ?? "0"), a => a.GetCustomAttribute<DescriptionAttribute>()?.Description ?? "");
        }

        public static T Parse<T>(string value) where T : Enum
        {
            return (T)Enum.Parse(typeof(T), value);
        }
    }
}
